﻿using System;
using System.Collections.Generic;

namespace VisualPureBasicIDE.CoreGUI
{
    /// <summary>
    /// Manages / caches objects which should only have exactly one instance (singleton)
    /// </summary>
    public static class InstanceManager
    {
        private static readonly Dictionary<Type, object> _instanceCache = new Dictionary<Type, object>();

        /// <summary>
        /// <para>Gets an instance of the given type out of the cache.</para>
        /// <para>If the instance does not exist in the cache, it is instanced the only time.</para>
        /// <para>NOTICE: If the ClearCache() function is called, the cache is freed of the instances of all classes / structs.</para>
        /// </summary>
        /// <param name="type">The type of the class / struct to return</param>
        /// <returns>An instance of the given type</returns>
        public static object GetInstance(Type type)
        {
            object instance;

            if (!_instanceCache.TryGetValue(type, out instance))
            {
                Logger.LogDebugMessage("InstanceManager - Object of type \"" + type + "\" not found in the cache. Creating new instance ...");

                instance = Activator.CreateInstance(type);
                _instanceCache.Add(type, instance);
            }
            else
                Logger.LogDebugMessage("InstanceManager - Object of type \"" + type + "\" found in the cache. Returning instance ...");

            return instance;
        }

        public static T GetInstance<T>() where T : class
        {
            return GetInstance(typeof (T)) as T;
        }

        public static void SetInstance(object instance)
        {
            var type = instance.GetType();

            if (_instanceCache.ContainsKey(type))
            {
                Logger.LogDebugMessage("InstanceManager - Object of type \"" + type + "\" already in cache. Overwriting ...");
                _instanceCache.Remove(type);
            }

            _instanceCache.Add(type, instance);
        }

        /// <summary>
        /// <para>Frees the cache of the instances of all classes / structs</para>
        /// <para>WARNING: All instances have to be recreated.</para>
        /// </summary>
        public static void ClearCache()
        {
            _instanceCache.Clear();
        }
    }
}